<?php
/**
 * 公用的函数库
 * 此文件提供了网站所应用到的共用函数文件
 */

/**
 * 获取/设置配置值
 */
function C($name=null, $value=null)
{
    static $_config = array();
    // 无参数时获取所有
    if(empty($name)) return $_config;
    // 优先执行设置获取或赋值
    if (is_string($name))
    {
        if (!strpos($name,'.'))
        {
            $name = strtolower($name);
            if (is_null($value))
                return isset($_config[$name])? $_config[$name] : null;
            $_config[$name] = $value;
            return;
        }
        // 二维数组设置和获取支持
        $name = explode('.',$name);
        $name[0]   = strtolower($name[0]);
        if (is_null($value))
            return isset($_config[$name[0]][$name[1]]) ? $_config[$name[0]][$name[1]] : null;
        $_config[$name[0]][$name[1]] = $value;
        return;
    }
    // 批量设置
    if(is_array($name))
        return $_config = array_merge($_config,array_change_key_case($name));

    return null;// 避免非法参数
}

function is_valid_client($client_type) {
	return in_array($client_type, array(0,1,2,3,4,5,6,7,8,9,10));
}
/**
 * 返回一个sess_id，一个md5的串
 * @param int user_id
 * @param string ip
 */
function sess_id($user_id='', $ip='')
{
	if (empty($user_id)) $user_id = 'r'.mt_rand();
	if (empty($ip)) $ip = get_ip();

	$s1 = substr((md5($user_id . $ip . time() . microtime(true) . mt_rand())), 8, 25);
	$s2 = substr(md5($s1), 8, 4);

	return $user_id.'-'.$s1.$s2;
}

/**
 * 得到一个友好显示的时间
 *
 * 不到一分钟，显示"*秒前"
 * 大于一分钟小于一小时，显示"*分钟前"
 * 大于一小时小于今天，显示"*时*分"
 * 大于今天小于昨天，显示"昨天"大于昨天小于前天，显示"前天"
 * 大于前天小于一年，显示"*月*日"；大于一年，显示"*年*月*日"
 *
 * note: 一年的是跨年了，而不是365天
 *
 * @param long $timestamp
*/
function date_friendly($timestamp,$sign = 0)
{
	if (!is_numeric($timestamp)) return '';

	$curr_stamp = time();
	$time = $curr_stamp - $timestamp;

	// 今天的开始时间
	$today = strtotime(date('Y-m-d', $curr_stamp)); /// $curr_stamp - $curr_stamp%86400;

	$ret = '';

	if ($time <= 0) $time = 1;

	// 不到一秒钟，显示"刚刚"
	if ($time < 1) $ret = '刚刚';
	// 不到一分钟，显示"*秒前"
	elseif ($time < 60) $ret = $time . '秒前';
	// 大于一分钟小于一小时，显示"*分钟前"
	elseif ($time < 3600) $ret = floor($time/60).'分钟前';
	// 大于一小时小于今天，显示"*时*分"
	elseif ($timestamp >= $today && $timestamp < ($today+86400)) {
	    if ($sign){
	    $ret = '今天'.date('H:i', $timestamp);
	    }else{
	        $ret = date('H:i', $timestamp);
	    }
	}
	// 大于前天小于一年，显示"*月*日"
	elseif (date('Y',$curr_stamp) == date('Y',$timestamp)) $ret = date('m月d日 H:i', $timestamp);
	// 大于一年，显示"yyyy年*月*日"
	else {
		$ret = date('Y年m月d日 H:i', $timestamp);
	}

	return $ret;
}

/**
 * 把一个字符串从大写=》小写
 *
 * @param string str
 */
function tolower($str) {

	return strtr($str, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
}

/**
 * 把一个字符串从小写=》大写
 *
 * @param string str
 */
function toupper($str) {

	return strtr($str, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
}

/**
 * 判断一个UTF8字符串的长度
 *
 * @param string $str
 * @param int $unit 1/2/3 中的一个值, default:2
 *           1表示$str每个汉字当做长度1来统计
 *           2表示$str每个汉字当做长度2来统计
 *           3表示$str每个汉字当做长度3来统计
 */
function strlen_utf8($str, $unit=2) {
	$len = 0;

	$result = substr_utf8($str, 0, strlen($str), true);
	$count = count($result);
	for ($i = 0; $i < $count; $i++) {
		$len += ord($result[$i]) > 127 ? $unit : 1;
	}
	return $len;
}

/**
 * UTF8字符串的子字符串函数
 *
 * @param string $str
 * @param string $start
 * @param string $length
 */
function substr_utf8($str, $start=0, $length=-1, $return_ary=false)
{
    $len = strlen($str);if ($length == -1) $length = $len;
    $r = array();
    $n = 0;
    $m = 0;

    for($i = 0; $i < $len; $i++) {
        $x = substr($str, $i, 1);
        $a  = base_convert(ord($x), 10, 2);
        $a = substr('00000000'.$a, -8);
        if ($n < $start) {
            if (substr($a, 0, 1) == 0) {
            }elseif (substr($a, 0, 3) == 110) {
                $i += 1;
            }elseif (substr($a, 0, 4) == 1110) {
                $i += 2;
            }
            $n++;
        }else {
            if (substr($a, 0, 1) == 0) {
                $r[] = substr($str, $i, 1);
            }elseif (substr($a, 0, 3) == 110) {
                $r[] = substr($str, $i, 2);
                $i += 1;
            }elseif (substr($a, 0, 4) == 1110) {
                $r[] = substr($str, $i, 3);
                $i += 2;
            }else {
                $r[] = '';
            }
            if (++$m >= $length) {
                break;
            }
        }
    }

    return $return_ary ? $r : implode('',$r);
}

/**
 * 字符串阶段，不管是汉字还是字母，都算一个字符
 */
function truncate_utf8($str, $len, $etc='...')
{

	$bak_str = $str;
	$str = substr_utf8($str, 0, strlen($str), true);

	/// 如果字符串长度小于截断长度，直接返回
	if ($len >= count($str)) return $bak_str;

	/// 26个字母
	/// i l I 占0.5
	/// 其他的占0.8 汉字 1.0
	$c = count($str);

	$total_len = 0;

	for ($i=0; $i < $c; $i++) {

		if (ord($str[$i]) > 127) {
			$total_len = $total_len + 1;
			$str[$i] = array($str[$i], 2);
		}
		elseif (in_array($str[$i], array('i', 'l', 'I'))) {
			$total_len = $total_len + 0.5;
			$str[$i] = array($str[$i], 1);
		}
		else {
			$total_len = $total_len + 0.8;
			$str[$i] = array($str[$i], 1);
		}

		if (ceil($total_len) >= $len) {

			$str = array_slice($str, 0, ($i+1));

			break;
		}
	}

	$total_len = ceil($total_len);

	$c = count($str);

	$etc_len = strlen($etc);
	$etc_len2 = 0;
	for ($i=($c-1); $i >=0; $i--) {

		if ($etc_len2 >= $etc_len) {

			$str = array_slice($str, 0, ($i+1));
			break;
		}

		$etc_len2 += $str[$i][1];
	}

	$c = count($str);
	$ret = '';
	for ($i=0; $i < $c; $i++) {
		$ret .= $str[$i][0];
	}

	return $ret.$etc;
}

//$sourcestr 是要处理的字符串
//$cutlength 为截取的长度(即字数)
function cut_str($sourcestr,$cutlength)
{
   $returnstr='';
   $i=0;
   $n=0;
   $k=0;
   $last_cutnum=0;
   $str_length=strlen($sourcestr);//字符串的字节数
   while ($i < $str_length)
   {
      $cut_num=0;
      $m=1;//字串长度计1
      $temp_str=substr($sourcestr,$i,1);
      $ascnum=Ord($temp_str);//得到字符串中第$i位字符的ascii码
      if ($ascnum>=224)    //如果ASCII位高与224，
      {
                      //字串长度计1
         $cut_num=3;         //实际Byte计为3
      }
      elseif ($ascnum>=192) //如果ASCII位高与192，
      {
                     //字串长度计1
         $cut_num=2;      //实际Byte计为2
      }
      elseif ($ascnum>=65 && $ascnum<=90) //如果是大写字母，
      {
                     //但考虑整体美观，大写字母计成一个高位字符
         $cut_num=1;     //实际的Byte数计1个
      }
      else                //其他情况下，包括小写字母和半角标点符号，
      {
         $m=0.5;        //小写字母和半角标点等与半个高位字符宽...
         $cut_num=1;     //实际的Byte数计1个
      }
      $n=$n+$m;//总占位长度
      if ($n <= $cutlength){
        $returnstr=$returnstr.substr($sourcestr,$i,$cut_num);
        $k=$n;//有效的占位长度
        $last_cutnum=$cut_num;
      }
      $i=$i+$cut_num;//字符长度
   }
    if ($k < $n){
        $last_cutnum=0-$last_cutnum;
        $returnstr=substr($returnstr,0,$last_cutnum);
        $returnstr = $returnstr . "...";//超过长度时在尾处加上省略号
    }
    return $returnstr;

}



/**
 * 检查字符串是否是UTF8编码
 *
 * @param string $string 字符串
 *
 * @return boolean
 */
function is_utf8($str)
{
	return preg_match('%^(?:
		 [\x09\x0A\x0D\x20-\x7E]            # ASCII
	   | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
	   |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
	   | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
	   |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
	   |  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
	   | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
	   |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
   )*$%xs', $str);
}

/**
 * MySQL指令安全过滤
 *
 * 支持数据递归过滤
 *
 * @param mixed data
 */
function mysql_escape_data($data)
{

	if (is_array($data) || is_object($data)) {
		foreach ($data as &$v) {
			$v = mysql_escape_data($v);
		}
	} else {
		return mysql_escape_string($data);
	}

	return $data;
}

/**
 * 字符串命名风格转换
 * type
 * =0 将Java风格转换为C的风格 UserModel=>user_model
 * =1 将C风格转换为Java的风格 user_model=>UserModel
 *
 * @param string name 字符串
 * @param int type 转换类型 default：1
 *
 * @return string
 */
function parse_name($name, $type=1)
{
    if ($type == 1) {
//         return ucfirst(preg_replace("/_([a-zA-Z0-9])/e", "strtoupper('\\1')", $name));
        return ucfirst(preg_replace_callback("/_([a-zA-Z0-9])/", function ($m) { return strtoupper($m[1]); }, $name));
    }
    else if ($type == 2) {
    	return (preg_replace_callback("/_([a-zA-Z0-9])/", function ($m) { return strtoupper($m[1]); }, $name));
    }
    else {
        $name = preg_replace("/[A-Z]/", "_\\0", $name);
        return strtolower(trim($name, "_"));
    }
}

/**
 * 得到某天的凌晨时间戳，默认是今天的凌晨时间戳
 *
 * @param int day_timestamp
 */
function get_lingchen_stamp($day_timestamp=0)
{

	if ($day_timestamp == 0) $day_timestamp = time();

	return strtotime(date('Y-m-d', $day_timestamp));
}

/**
 * 得到客户端IP
 */
function get_ip ()
{

     global $_SERVER;
     $ip = '';
     if (!empty($_SERVER['HTTP_QIEKE_REAL_IP'])) {
     	$ip = $_SERVER['HTTP_QIEKE_REAL_IP'];
     } else if (isset($_POST['QK_CLIENT_IP'])) {
     	$ip = $_POST['QK_CLIENT_IP'];
     } elseif (getenv('REMOTE_ADDR')) {
         $ip = getenv('REMOTE_ADDR');
     } elseif (getenv('HTTP_CLIENT_IP')) {
         $ip = getenv('HTTP_CLIENT_IP');
     } elseif (getenv('HTTP_X_FORWARDED_FOR')) {
         $ip = getenv('HTTP_X_FORWARDED_FOR');
     }
     return $ip;
}

/**
 * top redirect
 */
function top_redirect($url='') {
	if (empty($url)) $url = C('INDEX_URL');
    echo '<script type="text/javascript">top.window.location.href="'.$url.'"</script>';
    exit;
}

/**
 * 系统重定向函数
 *
 * @param string url, 重定向的URL，默认定向到网站首页
 * @param boolean clear_forward, true/false, default:false, 标记是否取消所有的重定向设置，如果取消了，用户登录，将会被定向到默认页面
 * @param string forward, 指定如果是重定向到登陆页，再次登录后跳转回来的页面地址，默认定向到当前页面，只有当clear_forward=false才有效
 * @param string $msg, optional
 * @param int $time, second, optional
 */
function redirect($url, $clear_forward=false, $forward='', $msg='', $time=0)
{

	if (empty($url)) {
		$url = C('INDEX_URL');
	}

	/// 没有指定如果是重定向到登陆页，再次登录后跳转回来的页面地址，设置为当前页面地址
	if (empty($forward)) {
		$forward = ((isset($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS']) != 'off')) ? 'https://' : 'http://').$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
	}

	if ($clear_forward) {
		Cookie::delete('forward');
	}
	else {
		Cookie::set('forward', urlencode($forward));
	}

    //多行URL地址支持
    $url = str_replace(array("\n", "\r"), '', $url);
    if(empty($msg))
        $msg    =   "系统将在{$time}秒之后自动跳转到{$url}！";

    /// 封装msg的样式
    $msg = '<div style="font-size:12px;color:#fff;background:#f90;line-height:24px;width:250px;text-align:center;">'.$msg.'</div>';

    if ((!headers_sent()) && (0 === $time)) {
    	header("Location: ".$url);
    	exit;
    }
    else {
        $str    = "<meta http-equiv='Refresh' content='{$time};URL={$url}'>";
        if($time!=0) {
            $str .= $msg;
        }
        exit($str);
    }
}

/**
 * 开始调试模式
 */
function debug() {
	static $debug_off = true;

	C('APP_DEBUG', true);
	if ($debug_off) {
		register_shutdown_function(array('App', 'showTrace'));
		$debug_off = false;
	}
}

function debug_start($k='') {

	debug();

	$t_key = '_t_debug_'.md5($k);
	$GLOBALS[$t_key] = microtime(true);

	Log::record(" 调试[".$k."]开始 >>",Log::DEBUG);
}

function debug_end($k='') {

	$t_key = '_t_debug_'.md5($k);
	if (!isset($GLOBALS[$t_key])) return;

	Log::record(" << 调试[".$k."]结束，本debug区间的执行时间是".(microtime(true)-$GLOBALS[$t_key])."秒",Log::DEBUG);
}

function api_log($str='') {

	if (empty($str)) return C('_api_log');

	$api_log = C('_api_log');

	if (empty($api_log)) {
		C('_api_log', $str);
		return true;
	}

	$api_log = $api_log.', '.$str;

	c('_api_log', $api_log);

	return true;
}

function web_api_log($str='') {
	if (empty($str)) {
	    return C('_web_api_log');
	} else if ($str===false) {
	    return C('_web_api_log','');
	}
	$web_api_log = C('_web_api_log');
	if(empty($web_api_log)){
	    C('_web_api_log', $str) ;
	} else {
	    C('_web_api_log',$web_api_log.','.$str);
	}
	return true;
}

/**
 * 后台脚本日志记录, 本函数待改进优化
 */
function do_log($log_name, $message, $level='INFO', $mkdir=false, $file_dir = '') {

	if ( $file_dir ) {
		$cron_log_dir = $file_dir;
	} else {
		$cron_log_dir = C('CRON_LOG_DIR');
	}
	if (!$cron_log_dir) {
		$cron_log_dir = APPLICATION_ROOT.'/cron_scripts/log/';
	}

	if ($mkdir) {
		@mkdir($cron_log_dir, 0777);
	}

	if (!empty($message)) {
		$destination = $cron_log_dir.$log_name.'-'.date('y_m_d').'.log';

		Log::write($message, $level, Log::FILE, $destination);
	}
}

/**
 * CRON相关的Log
 *
 * @param string str, Log字符串
 * @param int type, 默认1, 备用 1:普通 2:错误
 */
function cron_log($str, $type=1, $mkdir=false) {

	if (empty($str) && ($GLOBALS['cron_type'] == 'log')) {
		do_log('cron', $str, 'INFO', $mkdir);
	}
	else {
		if ($GLOBALS['cron_type'] == 'log') {
			do_log('cron', $GLOBALS['cron_prefix'].$str, 'INFO', $mkdir);
		}
		else {
			echo $GLOBALS['cron_prefix'].$str." [".date('Y-m-d H:i:s', time())."]\n";
		}
	}
}

/**
 * 浏览器友好的变量输出
 *
 * @param mixed $var
 * @param boolean $echo
 * @param mixed $label
 * @param boolean $strict
 *
 * @example dump($var_ary);
 *
 * @author wangyihuang <wangyihuang@gmail.com>
 */
function dump($var) {

	if (!headers_sent()) header('Content-type: text/html; charset=utf-8'); // temp

    $label = '';

     if(!extension_loaded('xdebug')) {
	    ob_start();
	    var_dump($var);
	    $output = ob_get_clean();

        $output = preg_replace("/\]\=\>\n(\s+)/m", "] => ", $output);
        $output = '<pre>'. $label. htmlspecialchars($output, ENT_QUOTES). '</pre>';

        echo $output;
        return ;
    }
    else {
    	ini_set('xdebug.var_display_max_children', 1024 );//xdebug.var_display_max_children Type: integer, Default value: 128
    	ini_set('xdebug.var_display_max_data', 10240 );//Type: integer, Default value: 512
    	ini_set('xdebug.var_display_max_depth', 10);

    	if (is_array($var)) {
    		var_dump($var);
    	}
    	else {
    		echo $var.'<br />';
    	}
    	return ;
    }
}

function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {

	$ckey_length = 4;

	$key = md5($key);
	$keya = md5(substr($key, 0, 16));
	$keyb = md5(substr($key, 16, 16));
	$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';

	$cryptkey = $keya.md5($keya.$keyc);
	$key_length = strlen($cryptkey);

	$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
	$string_length = strlen($string);

	$result = '';
	$box = range(0, 255);

	$rndkey = array();
	for($i = 0; $i <= 255; $i++) {
		$rndkey[$i] = ord($cryptkey[$i % $key_length]);
	}

	for($j = $i = 0; $i < 256; $i++) {
		$j = ($j + $box[$i] + $rndkey[$i]) % 256;
		$tmp = $box[$i];
		$box[$i] = $box[$j];
		$box[$j] = $tmp;
	}

	for($a = $j = $i = 0; $i < $string_length; $i++) {
		$a = ($a + 1) % 256;
		$j = ($j + $box[$a]) % 256;
		$tmp = $box[$a];
		$box[$a] = $box[$j];
		$box[$j] = $tmp;
		$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
	}

	if($operation == 'DECODE') {
		if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
			return substr($result, 26);
		} else {
			return '';
		}
	} else {
		return $keyc.str_replace('=', '', base64_encode($result));
	}
}

/**
 * 取得对象实例 支持调用类的静态方法
 *
 * @param string $name，对象类名
 * @param string $method，对象静态方法名
 * @param array $args，$method要传入的参数
 */
function get_instance_of($name, $method='',$args=array())
{

    static $_instance = array();
    $identify   =   empty($args)?$name.$method:$name.$method.to_guid_string($args);

    if (!isset($_instance[$identify])) {
        if(class_exists($name)){
            $o = new $name();
            if($method && method_exists($o,$method)){
                if(!empty($args)) {
                    call_user_func_array(array(&$o, $method), $args);
                }else {
                    $o->$method();
                }
            }
            $_instance[$identify] = $o;
        }
        else
            halt('实例化一个不存在的类！:'.$name);
    }

    return $_instance[$identify];
}

/**
 * 自定义异常处理
 */
function throw_exception($msg, $type='AppException', $code=0) {
    if(IS_CLI) exit($msg);
    if(class_exists($type, false))
        throw new $type($msg, $code, true);
    else
        halt($msg);        // 异常类型不存在则输出错误信息字串
}

// 错误输出
// type=1 异常
// type=2 错误
function halt($error, $type=1) {

    if(IS_CLI) exit($error);
    $msg=date("Y-m-d H:i:s")."\n";
    $msg.=$_SERVER['REQUEST_URI']."\n";
    if(is_array($error)){
    	foreach ($error as $key=>$value) {
    		$msg.="$key:$value\n";
    	}
    }
    else{
    	$msg.=$error."\n";
    }
//    error_log($msg, 3,  "/tmp/error." . date("Y-m-d") . ".log");
    if (in_array(RUN_MOD, array('test2', 'deploy'))) {
    	header('Location:'.C('INDEX_URL').'/unfound');
    	exit;
    }
    $e = array();
    if (C('APP_DEBUG')) {
        //调试模式下输出错误信息
        if(!is_array($error)) {
            $trace = debug_backtrace();
            $e['message'] = $error;
            $e['file'] = $trace[0]['file'];
            $e['class'] = $trace[0]['class'];
            $e['function'] = $trace[0]['function'];
            $e['line'] = $trace[0]['line'];
            $traceInfo='';
            $time = date("y-m-d H:i:m");
            foreach($trace as $t) {
                $traceInfo .= '['.$time.'] '.$t['file'].' ('.$t['line'].') ';
                $traceInfo .= $t['class'].$t['type'].$t['function'].'(';
                $traceInfo .= implode(', ', $t['args']);
                $traceInfo .=")<br/>";
            }
            $e['trace']  = $traceInfo;
        }
        else {
            $e = $error;
        }

        // 包含异常页面模板
        include C('APP_EXCEPTION_FILE');
    }
    else
    {
        //否则定向到错误页面
        $error_page = C('ERROR_PAGE');
        if(!empty($error_page)) {
            redirect($error_page);
        }
        else {
            if(C('SHOW_ERROR_MSG'))
                $e['message'] =  is_array($error)?$error['message']:$error;
            else
                $e['message'] = C('ERROR_MESSAGE');

            // 包含异常页面模板
            include C('APP_EXCEPTION_FILE');
        }
    }
    exit;
}

/**
 * 根据PHP各种类型变量生成唯一标识号
 */
function to_guid_string($mix) {
    if(is_object($mix) && function_exists('spl_object_hash')) {
        return spl_object_hash($mix);
    }elseif(is_resource($mix)){
        $mix = get_resource_type($mix).strval($mix);
    }else{
        $mix = serialize($mix);
    }
    return md5($mix);
}

/**
 * 是否是合法的Email
 *
 * @param mixed $email
 *
 * @return boolean
 */
function is_email($email) {
	if (!eregi("^([a-z0-9_]|\\-|\\.)+@(([a-z0-9_]|\\-)+\\.)+[a-z]{2,4}$", $email)) return false;
	return true;
}

/**
 * 是否非空
 *
 * @param mixed $var
 *
 * @return boolean
 */
function no_empty($var) {return _regex($var, 'require');}

/**
 * 是否是URL
 *
 * @param mixed $url
 *
 * @return boolean
 */
function is_url($url) {return _regex($url, 'url');}

/**
 * 是否是currency
 *
 * @param mixed $currency
 *
 * @return boolean
 */
function is_currency($currency) {return _regex($currency, 'currency');}

/**
 * 是否是数字
 *
 * @param mixed $num
 *
 * @return boolean
 */
function is_number($num) {return _regex($num, 'number');}

/**
 * 是否是邮编
 *
 * @param mixed $zip
 *
 * @return boolean
 */
function is_zip($zip) {return _regex($zip, 'zip');}

/**
 * 是否是字母
 *
 * @param mixed $var
 *
 * @return boolean
 */
function is_english($var) {return _regex($var, 'english');}

/**
 * 判断手机是否合法，11位，且以13、15、18开头
 */
function is_phone($var) {return _regex($var, 'phone'); }

/**
 * 判断QQ号码是否合法，QQ号码必须是数字或者以qq.com结尾的邮箱
 */
function is_qq($var) {
	$regex1 = '/^[1-9]\d{4,15}$/';
	$regex2 = '/^[0-9a-zA-Z_\-\.]+@qq\.com$/';

	if (preg_match($regex1, $var)) return true;
	if (preg_match($regex2, $var)) return true;

	return false;
}

/**
 * Created on 2010-6-16
 *
 * 判断是否json数据
 *
 */
function is_json( &$str ) {
	if ($str[0] == '{' || $str[0] == '[') {
		return true;
	}
	return false;
}

function _regex($value,$rule) {
    $validate = array(
        'require'=> '/.+/',
        'email' => '/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/',
        'url' => '/^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$/',
        'currency' => '/^\d+(\.\d+)?$/',
        'number' => '/\d+$/',
        'zip' => '/^[1-9]\d{5}$/',
        'integer' => '/^[-\+]?\d+$/',
        'double' => '/^[-\+]?\d+(\.\d+)?$/',
        'english' => '/^[A-Za-z]+$/',
        'phone' => '/^1(3|5|8)\d{9}$/',
        'qq' => '/^[1-9]\d{4,15}(@qq\.com)?$/',
    );

    // 检查是否有内置的正则表达式
    if(!isset($validate[strtolower($rule)])) return false;

    $rule   =   $validate[strtolower($rule)];

    return preg_match($rule,$value)===1;
}

/**
 * 跨IDC，得到当前运行模式的本地的队列配置
 * lq: local queue
 *
 * @param string qname, 队列的名称 IDC_QUEUE/IDC_REMOTEQUEUE，默认是IDC_QUEUE
 */
function get_idc_lq($qname='') {

	if (empty($qname)) $qname = IDC_QUEUE;

	$idc_list = $GLOBALS['RUN_MOD_LIST'];

	if (!isset($idc_list[RUN_MOD])) {
		trigger_error(__FUNCTION__.': 非法的运行模式：'.RUN_MOD.'！', E_USER_ERROR);
	}

	$cfg = $idc_list[RUN_MOD];

	$queue_conf = array(
		'hosts' => array(
			's1' => array(
				'host' => $cfg['queue']['host'],
				'port' => $cfg['queue']['port'],
			),
		),

		'queues' => array(
			$qname => array(
				'server_id' => array('s1'),
			),
		),
	);

	return $queue_conf;
}

/**
 * 跨IDC，得到当前运行模式的远程的队列配置
 * rq: remote queue
 */
function get_rsync_rq_list($qname = '') {

	if (empty($qname)) $qname = IDC_REMOTEQUEUE;

	$idc_list = $GLOBALS['RUN_MOD_LIST'];

	if (!isset($idc_list[RUN_MOD])) {
		trigger_error(__FUNCTION__.': 非法的运行模式：'.RUN_MOD.'！', E_USER_ERROR);
	}

	$cfg = $idc_list[RUN_MOD];

	$idc_total = $cfg['idc_total'];

	if ($idc_total <= 1) {
		return array();
	}

	$idc_total--;

	$qconf = get_idc_lq($qname);

	$ret = array();
	$rqconf = $qconf;
	for ($i=0; $i < $idc_total; $i++) {

		$rqconf['hosts']['s1']['host'] = 'r'.($i+1).'.'.$qconf['hosts']['s1']['host'];

		$ret[] = $rqconf;
	}

	return $ret;
}

//[RUNTIME]
// 编译文件
function compile($filename,$runtime=false) {
    $content = file_get_contents($filename);
    $content = trim($content);
    // 替换预编译指令
//    $content = preg_replace('/\/\/\[RUNTIME\](.*?)\/\/\[\/RUNTIME\]/s','',$content);
    $content = substr(trim($content),5);
    if('?>' == substr($content,-2))
        $content = substr($content,0,-2);
    return $content;
}

// 去除代码中的空白和注释
function strip_whitespace($content) {
    $stripStr = '';
    //分析php源码
    $tokens =   token_get_all($content);
    $last_space = false;

    for ($i = 0, $j = count ($tokens); $i < $j; $i++) {

        if (is_string ($tokens[$i])) {
            $last_space = false;
            $stripStr .= $tokens[$i];
        }
        else {
            switch ($tokens[$i][0]) {
                //过滤各种PHP注释
                case T_COMMENT:
                case T_DOC_COMMENT:
                    break;
                //过滤空格
                case T_WHITESPACE:
                    if (!$last_space) {
                        $stripStr .= ' ';
                        $last_space = true;
                    }
                    break;
                default:
                    $last_space = false;
                    $stripStr .= $tokens[$i][1];
            }
        }
    }

    return $stripStr;
}

/**
 * 公用返回JS的方法
 * @param $js_name js的命字 例如 uvan_get_js("global") uvan_get_js("active/post",JS_VERSION);
 * @version JS的版本号 建议各子频道设置自己的单独的JS或是CSS的版本号 然后传值自己的版本号
 *
 * 或是各频道自己再封装一下
 *   define("ACTIVE_JS_VERSION",date("Y-m-d"));
 *   function active_get_js($js_name) {
 *      return uvan_get_js($js_name,ACTIVE_JS_VERSION);
 *   }
 */
function uvan_get_js($js_name, $version="") {
    return "<script src=\"".C("JS_DOMAIN")."/js/".$js_name.".js?".$version."\" type=\"text/javascript\"></script>\n";
}

//公用返回CSS的方法
function uvan_get_css($css_name,$version=""){
    return "<link rel=\"stylesheet\" href=\"".C("CSS_DOMAIN")."/css/".$css_name.".css?".$version."\" type=\"text/css\" />\n";
}


//

//[/RUNTIME]


//作用：转换HTML特殊字符
//参数：	$str			转换的字符串
//				$length		截取的长度
//				$dot			后缀
//返回：	$str			转换完成的字符串
    function chgHtmlSpecialChar( $str ){
         return $str;//暂时取消转换
      if( is_array( $str ) ){
        foreach( $str as $skey => $value ){
          $str[$skey] = chgHtmlSpecialChar( $value);
        }
      }else{
        $str = htmlspecialchars( $str );
      }
      return $str;
    }
/*
	 * @gaixiaohui 通用编辑框
	 * @param -> $model:"simple"(简易模式)
	 * @param -> $app:"topic"(话题),"note"(记录)
	 * @param -> $project:"home"(家园),"dest"(地点)
	 * @param -> $data:(传入的数据)
	 * */
function editTemp($model='',$app='',$project='',$data='',$opmode=0,$sync=0){
	$d = $data;
	if($project == 'home'){
		$e = '<div class="e-edit"><a id="poi_edit" href="#">[修改]</a></div><!--end e-edit-->';
	}else{
		$e = '<div class="e-edit"></div><!--end e-edit-->';
	}

	$btn = '';

	if($app == 'topic'){
		$style = 'ed-full';
		$btn = '';
		$btn2 = '';
	}else{
		$style = 'ed-full';
		$btn = '';
		$btn2 = '<span class="icon-topic"></span><span id="msg_topic" class="color-1">插入话题</span>';
	}

	if($project == 'dest'){
		$recommend = '';
		$style3 = 'ed-dest';
	}else{
		$style3 = 'ed-home';
		$recommend = '';
	}

	if($sync == 0){
		$txt_sync = '';
	}else{
		$txt_blcok='<div class=c_c1    id="snsblock" ><span class=c_c11>同步到：</span>
		<span class=c_c12>
<a   id="tangguo1" name="tangguo1" ><img class="icon-tg2" title="糖果" src="'.C('IMG_DOMAIN').'/images/global/blank.gif"></a>
<a   id="sina1" name="sina1" ><img class="icon-sina2" title="新浪微博" src="'.C('IMG_DOMAIN').'/images/global/blank.gif"></a>
<a   id="qq1" name="qq1"><img class="icon-tx2" title="腾讯微博" src="'.C('IMG_DOMAIN').'/images/global/blank.gif"></a>
<a   id="renren1" name="renren1" ><img class="icon-renren2" title="人人网" src="'.C('IMG_DOMAIN').'/images/global/blank.gif"></a>
<a   id="kaixin0011" name="kaixin0011"><img class="icon-kaixin2" title="开心网" src="'.C('IMG_DOMAIN').'/images/global/blank.gif"></a>
<a   id="douban1" name="douban1" ><img class="icon-douban2" title="豆瓣网" src="'.C('IMG_DOMAIN').'/images/global/blank.gif"></a>
<a   id="foursquare1" name="foursquare1"><img class="icon-foursquare2" title="Foursquare" src="'.C('IMG_DOMAIN').'/images/global/blank.gif"></a>
<a   id="facebook1" name="facebook1"><img class="icon-facebook2" title="Facebook" src="'.C('IMG_DOMAIN').'/images/global/blank.gif"></a>
<a  id="twitter1" name="twitter1"><img class="icon-twitter2" title="Twitter" src="'.C('IMG_DOMAIN').'/images/global/blank.gif"></a>
		</span>
</div>';
		$txt_sync =$txt_blcok. '<input type="hidden" value="1"  class="check" id="txt_sync"/><p style="display:none">同步到绑定网站</p>';
	}

	$style2 = '';
	//if($model != "simple"){
		$html = '<div class="edit png_bg '.$style.'" id="edit_box">
					<div class="e-t '.$style3.'" >
						<div class="et-i">
							<div class="e-btn"><b id="poi_name">';
		if($opmode==0)$html.='@<script type="text/javascript">document.write(param.poi_name);</script>';
		$html .= '</b></div><!--end e-btn-->'.$e.'
							<div class="clear"></div>
							'.$recommend.$btn.'
						</div>
					</div><!--end e-t-->
					<div class="e-m">
						<div class="e-m-i">
							<textarea autocomplete="off" id="msg_txt" name="msg_txt" '.$style2.'>'.$d.'</textarea>
							<div id="quick_pic">
								<div>
									<span id="sum_txt"><em class="color-3">140</em></span>
									<span style="display: none;" id="warning_txt"></span>
								</div>
							</div>
						</div>
						<div class="ib-operate">
							<div class="ibo-l fleft">
								'.$btn2.'
								<span class="icon-photo"></span><span id="upload_pic" class="color-1">添加照片</span>
							</div>
							<div class="ibo-r fright">
								'.$txt_sync.'<input type="button" id="t_submit" value="" class="sub-edit">
							</div>
							<div class="clear"></div>
						</div>
					</div><!--end e-m-->
				</div><!--end edit-->';
	//}
	return $html;
}

//分发系统接口,to fix
function super_dispatch_pic($path,$port)
{
	return dispatch_pic('localhost',$port,$path);
}

//分发系统接口
function dispatch_pic($host,$port,$path)
{
	$ret = core_send_html_req("http://$host:$port/$path");
	return $ret == 'success' ? true: false;
}

function core_send_html_req($url)
{
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
        $data = curl_exec($curl);
        curl_close($curl);
        return $data;
}

function genScript($params=array(),$mode=0,$suffix='js'){
	$p = array();
	switch($suffix){
		case 'js' :
			$p['version'] = C('SITE_DEF_JS_VERSION');
			break;
		case 'css' :
			$p['version'] = C('SITE_DEF_CSS_VERSION');
			break;
		default:
			$p['version'] = C('SITE_DEF_JS_VERSION');
			break;
	}
	if( !empty( $_GET['script_debug'] ) && ( intval($_GET['script_debug'])===1 ) ){
		$p['debug'] = 'debug=1';
	}
	$p = implode('&',$p);
	switch($mode){
		case 0 :
			$queryString = implode('&',$params);
			return 'gen/'.md5($queryString).'.'.$suffix.'?'.$p;
			break;
		case 1 :
			$arrQueryString = array();
			foreach($params as $k=>$v){
				$arrQueryString = array_merge($arrQueryString,array($k.'='.$v));
			}
			$queryString = implode('&',$arrQueryString);
			return $queryString.'?'.$p;
			break;
	}
}

function send_result($code=0, $msg='未知错误', $data=array()) 
{
    $ret = array(
        'status'=>$code,
        'error' =>$msg,
    );

    $ret['data'] = $data;

    $callback = isset($_GET['callback']) ? $_GET['callback'] : '';

    if ($callback) {
        echo $callback.'('.json_encode($ret).')';
    }
    else {
        echo json_encode($ret);
    }
    exit;
}


/**
 *
 * 封装smarty全局单例函数
 */
function getSmartyInstance() {
    static $smarty;
    if ($smarty) {
        return $smarty;
    }
    $smarty = new Smarty();
    $smarty->template_dir = ROOT_PATH . "/smarty/templates/" . APP_NAME . "/";
    $smarty->compile_dir = ROOT_PATH . "/smarty/templates_c/";
    $smarty->config_dir = ROOT_PATH . "/smarty/configs/";
    $smarty->cache_dir = ROOT_PATH . "/smarty/cache/";
    $smarty->caching = false;		// 默认不开启缓存
    $smarty->left_delimiter = '{';
    $smarty->right_delimiter = '}';

    return $smarty;
}


